#include "player.h"

#include <QDebug>

AudioPlayer::AudioPlayer() {
    engineObject = nullptr;
    engineEngine = nullptr;
    outputMixObject = nullptr;
    bufferQueueObject = nullptr;
    playInterface = nullptr;
    bufferQueueInterface = nullptr;
    m_audioBuffer = nullptr;
    m_bufferSize = 0;
    // 初始化OpenSL ES环境
    if (!initOpenSLES()) {
        // 如果初始化失败，可以在这里添加错误处理逻辑，比如抛出异常或者记录错误日志
        qDebug() << "init open sles failed!";
    }
}

AudioPlayer::~AudioPlayer() {
    // 销毁相关OpenSL ES对象
    if (bufferQueueObject!= nullptr) {
        (*bufferQueueObject)->Destroy(bufferQueueObject);
    }
    if (outputMixObject!= nullptr) {
        (*outputMixObject)->Destroy(outputMixObject);
    }
    if (engineObject!= nullptr) {
        (*engineObject)->Destroy(engineObject);
    }

    m_audioBuffer = nullptr;
}

bool AudioPlayer::initOpenSLES() {
    SLresult result;

    // 创建OpenSL ES引擎对象
    result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }
    // 实例化引擎
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 获取引擎接口
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 创建输出混音器对象
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 实例化输出混音器
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 配置音频数据源为缓冲队列
    SLDataLocator_AndroidSimpleBufferQueue locatorBufferQueue = {
        SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2
    };
    SLDataFormat_PCM formatPCM = {
        SL_DATAFORMAT_PCM,
        (SLuint32) m_numChannels,
        (SLuint32) m_sampleRate,
        SL_PCMSAMPLEFORMAT_FIXED_16,
        SL_PCMSAMPLEFORMAT_FIXED_16,
        SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
        SL_BYTEORDER_LITTLEENDIAN
    };
    SLDataSource audioSrc = {&locatorBufferQueue, &formatPCM};

    // 配置音频输出到设备
    SLDataLocator_OutputMix locatorOutputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
    SLDataSink audioSnk = {&locatorOutputMix};

    // 创建音频播放器
    const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE};
    const SLboolean req[] = {SL_BOOLEAN_TRUE};
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bufferQueueObject, &audioSrc, &audioSnk,
                                                sizeof(ids) / sizeof(SLInterfaceID), ids, req);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 实例化音频播放器
    result = (*bufferQueueObject)->Realize(bufferQueueObject, SL_BOOLEAN_FALSE);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 获取播放接口
    result = (*bufferQueueObject)->GetInterface(bufferQueueObject, SL_IID_PLAY, &playInterface);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 获取缓冲队列接口
    result = (*bufferQueueObject)->GetInterface(bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueueInterface);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    // 注册音频数据回调函数
    result = (*bufferQueueInterface)->RegisterCallback(bufferQueueInterface, bqPlayerCallback, this);
    if (result!= SL_RESULT_SUCCESS) {
        return false;
    }

    return true;
}

void AudioPlayer::bqPlayerCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void *context) {
    AudioPlayer *player = static_cast<AudioPlayer *>(context);
    // 在这里可以根据需要再次填充音频缓冲区数据并提交给缓冲队列，示例简单返回表示播放结束
    SLresult result = (*bufferQueue)->Enqueue(bufferQueue, player->m_audioBuffer, player->m_bufferSize);
    if (result!= SL_RESULT_SUCCESS) {
        // 处理入队失败的情况，比如停止播放等
    }
}

void AudioPlayer::play(void *buffer, int bufferSize, int numChannels, int sampleRate) {
    m_audioBuffer = buffer;
    m_bufferSize = bufferSize;
    m_numChannels = numChannels;
    m_sampleRate = sampleRate;

    // 启动音频播放
    SLresult result = (*playInterface)->SetPlayState(playInterface, SL_PLAYSTATE_PLAYING);
    if (result!= SL_RESULT_SUCCESS) {
        // 处理播放启动失败的情况
        qDebug() << "start play failed!";
    }

    // 初次提交音频数据到缓冲队列，触发回调开始播放
    result = (*bufferQueueInterface)->Enqueue(bufferQueueInterface, m_audioBuffer, m_bufferSize);
    if (result!= SL_RESULT_SUCCESS) {
        // 处理入队失败的情况
        qDebug() << "enque failed!";
    }
}
